<template>
    <div class="boxs">
        <el-card>
            <div slot="header" class="clearfix">
                <span>makeup-analysis</span>
            </div>
            <el-form class="demo-form-inline" :model="form" :rules="rules" ref="ruleForm">
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="addVersion" style="display: block;width: 100%;" label-position="top"
                            prop="prompt_test">
                            <el-button type="primary" @click="openAddVersion" icon="el-icon-plus
">add</el-button>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="version" style="display: block;width: 100%;" label-position="top"
                            prop="prompt_test">
                            <el-select v-model="queryParams.version" @change="handleQuery">
                                <el-option v-for="item in versionList" :key="item.id" :label="item.name"
                                    :value="item.id"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="prompt" style="display: block;width: 100%;" label-position="top"
                            prop="prompt_test">
                            <el-input autosize type="textarea" v-model="form.prompt_test" placeholder="请输入提示词"
                                resize="none" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20">
                    <el-col :span="8">
                        <el-form-item label="model" label-position="top" prop="model_test">
                            <div style="display: flex;align-items: center;">
                                <el-input v-model="form.model_test" placeholder="Ai 模型" />
                                <el-tooltip class="item" style="margin-left: 10px;" effect="dark" content="Ai 模型"
                                    placement="top-end">
                                    <i class="el-icon-info" style="cursor: pointer;"></i>
                                </el-tooltip>
                            </div>
                        </el-form-item>

                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="Temperature" label-position="top" prop="temperature_test">
                            <div style="display: flex;align-items: center;">
                                <el-input v-model="form.temperature_test" type="number" placeholder="通常在 0 到 1 之间" />

                                <el-tooltip class="item" style="margin-left: 10px;" effect="dark"
                                    content="控制生成文本的随机性。值越低，输出越确定；值越高，输出越随机。通常在 0 到 1 之间。" placement="top-end">
                                    <i class="el-icon-info" style="cursor: pointer;"></i>
                                </el-tooltip>
                            </div>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="Top P" label-position="top" prop="top_p_test">
                            <div style="display: flex;align-items: center;">
                                <el-input v-model="form.top_p_test" type="number" placeholder="请输入Top P" />
                                <el-tooltip class="item" style="margin-left: 10px;" effect="dark"
                                    content="核采样。与 temperature 类似，但通过考虑概率分布的累积来限制选择。值为 0.1 意味着只考虑概率前 10% 的标记。"
                                    placement="top-end">
                                    <i class="el-icon-info" style="cursor: pointer;"></i>
                                </el-tooltip>
                            </div>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20">
                    <el-col :span="8">
                        <el-form-item label="Frequency penalty" label-position="top" prop="frequency_penalty_test">
                            <div style="display: flex;align-items: center;">
                                <el-input v-model="form.frequency_penalty_test" type="number"
                                    placeholder="-2.0 到 2.0" />
                                <el-tooltip class="item" style="margin-left: 10px;" effect="dark"
                                    content="控制生成文本中重复词语的惩罚。值越高，重复词语的可能性越小。范围通常在 -2.0 到 2.0 之间。" placement="top-end">
                                    <i class="el-icon-info" style="cursor: pointer;"></i>
                                </el-tooltip>
                            </div>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="Presence penalty" label-position="top" prop="presence_penalty_test">

                            <div style="display: flex;align-items: center;">
                                <el-input v-model="form.presence_penalty_test" type="number" placeholder="-2.0 到 2.0" />
                                <el-tooltip class="item" style="margin-left: 10px;" effect="dark"
                                    content="控制生成文本中引入新词语的惩罚。值越高，模型更倾向于引入新词语。范围通常在 -2.0 到 2.0 之间。" placement="top-end">
                                    <i class="el-icon-info" style="cursor: pointer;"></i>
                                </el-tooltip>
                            </div>
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="Max tokens" label-position="top" prop="max_tokens_test">
                            <div style="display: flex;align-items: center;">
                                <el-input v-model="form.max_tokens_test" type="number" placeholder="请输入最大令牌数" />
                                <el-tooltip class="item" style="margin-left: 10px;" effect="dark"
                                    content="限制生成文本的最大长度。这个值决定了 API 可以返回的最大标记数。" placement="top-end">
                                    <i class="el-icon-info" style="cursor: pointer;"></i>
                                </el-tooltip>
                            </div>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20">
                    <el-col :span="24">
                        <el-form-item label="选择图片输入方式" label-position="top" prop="imageOption">
                            <el-radio-group v-model="form.imageOption">
                                <el-radio label="link">输入图片链接</el-radio>
                                <el-radio label="upload">上传图片</el-radio>
                            </el-radio-group>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20">
                    <el-col :span="12" v-show="form.imageOption === 'link'">
                        <el-form-item label="图片链接" label-position="top" prop="imageUrl">
                            <el-input v-model="form.imageUrl" placeholder="请输入图片链接" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12" v-show="form.imageOption === 'upload'">
                        <el-form-item label="上传图片" label-position="top" prop="imageUrl">
                            <el-upload action="https://jsonplaceholder.typicode.com/posts/" list-type="picture" multiple
                                :http-request="uploadHandel" :on-remove="remeveFile" :file-list="fileList" ref="upload"
                                :limit="1">
                                <el-button size="small" type="primary">点击上传</el-button>
                            </el-upload>
                            <el-progress v-if="uploadProgress > 0" :percentage="uploadProgress"></el-progress>
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
            <el-row :gutter="80">
                <el-col :span="8">
                    <el-button type="warning" :loading="bloading" @click="submitForm">运行</el-button>
                    <el-button type="primary" @click="submitForm1">更新至线上</el-button>
                </el-col>
            </el-row>
        </el-card>

        <el-dialog title="result" :visible.sync="dialogVisible" width="800px" :before-close="handleClose">
            <div>
                <v-md-preview :text="messageRes.content"></v-md-preview>
            </div>
        </el-dialog>
        <el-dialog title="addVersion" :visible.sync="dialogVisible1" width="500px" :before-close="handleClose1">
            <div style="padding: 20px 30px;padding-bottom: 0;">
                <el-form :model="form1" :rules="rules1" ref="ruleForm1">
                    <el-row>
                        <el-col :span="24">
                            <el-form-item label="addVersion" prop="version">
                                <el-input v-model="form1.version" placeholder="例:1.0.0" />

                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-form>
            </div>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible1 = false">{{ $t('review.close') }}</el-button>
                <el-button :type="form.id ? 'primary' : 'primary'" @click="affirm" :loading="addLoading">{{
                    $t('review.confirm')
                }}</el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script>
import { upload, getMakeupConfig, updateMakeupConfig, updateMakeupConfigHandel, getMakeupVersionList, addMakeupVersion } from "@/api/beauty";
export default {
    name: "review",
    data() {
        return {
            bloading: false,
            dialogVisible: false,
            dialogVisible1: false,
            updateLoading: false,
            addLoading: false,
            messageRes: {
                content: ''
            },
            form: {
            },
            form1: {
                version: ''
            },
            fileList: [],
            versionList: [

            ],
            queryParams: {
                version: ''
            },
            rules: {
                prompt_test: [{ required: true, message: '请输入提示词', trigger: 'blur' }],
                model_test: [{ required: true, message: '请输入模型', trigger: 'blur' }],
                temperature_test: [{ required: true, message: '请输入温度', trigger: 'blur' }],
                top_p_test: [{ required: true, message: '请输入Top P', trigger: 'blur' }],
                frequency_penalty_test: [{ required: true, message: '请输入频率惩罚', trigger: 'blur' }],
                presence_penalty_test: [{ required: true, message: '请输入存在惩罚', trigger: 'blur' }],
                max_tokens_test: [{ required: true, message: '请输入最大令牌数', trigger: 'blur' }],
                imageOption: [{ required: true, message: '请选择图片输入方式', trigger: 'change' }],
                imageUrl: [{ required: true, message: '图片不能为空', trigger: 'blur' }],
                fileList: [{ required: true, message: '请上传图片', trigger: 'change' }],
            },
            rules1: {
                version: [{ required: true, message: '请输入版本号(例:1.0.0)', trigger: 'blur' }],

            },
        };
    },
    created() {
        this.getversionList();

        //this.getMore();
    },
    methods: {
        validateVersionFormat(version) {
            const regex = /^\d+\.\d+\.\d+$/;
            return regex.test(version);
        },
        openAddVersion() {
            this.dialogVisible1 = true
        },
        async getversionList() {
            this.elloading = this.$loading({
                lock: true,
                text: 'Loading',
                spinner: 'el-icon-loading',
                background: 'rgba(0, 0, 0, 0.7)'
            });
            const { data } = await getMakeupVersionList()
            this.queryParams.version = data[data.length - 1].id;
             this.getMore();

            this.versionList = data
        },
        submitForm1() {
            if (!this.form.imageUrl) {
                this.form.imageUrl='-'
            }
            this.$refs.ruleForm.validate(async (valid) => {
                if (valid) {
                    this.$confirm('确定把配置信息更新到线上吗？', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: "error",
                    }).then(async () => {
                        this.elloading = this.$loading({
                            lock: true,
                            text: 'Loading',
                            spinner: 'el-icon-loading',
                            background: 'rgba(0, 0, 0, 0.7)'
                        });
                        this.updateLoading = true

                        await updateMakeupConfig(this.form)
                        await updateMakeupConfigHandel(this.form)
                        this.getMore();
                        this.$message({
                            message: "success!",
                            type: "success",
                        });
                        this.updateLoading = false

                    });

                } else {
                    console.log('提交失败');
                    return false;
                }
            });

        },
        handleClose() {
            this.elloading = this.$loading({
                lock: true,
                text: 'Loading',
                spinner: 'el-icon-loading',
                background: 'rgba(0, 0, 0, 0.7)'
            });
            this.messageRes.content = ''
            this.dialogVisible=false
            this.getMore();
        },
        handleClose1() {
            this.form1.version = ''
            this.dialogVisible1 = false
        },
        async uploadHandel(e) {
            const loading = this.$loading({
                lock: true,
                text: 'Loading',
                spinner: 'el-icon-loading',
                background: 'rgba(0, 0, 0, 0.7)'
            });

            const formData = new FormData();
            formData.append('file', e.file);
            let res = await upload(formData)
            this.uploading = false;
            this.form.imageUrl = res.fileUrl;
            loading.close();
        },
        remeveFile() {
            this.form.imageUrl = "";
            this.fileList = []
        },
        handlePreview(file) {
            console.log('Preview:', file);
        },
        handleRemove(file, fileList) {
            console.log('Remove:', file, fileList);
            this.fileList = fileList;
        },
        handleSuccess(response, file, fileList) {
            console.log('Success:', response, file, fileList);
            this.fileList = fileList;
        },
        submitForm() {
            this.bloading = true
            this.$refs.ruleForm.validate(async (valid) => {
                if (valid) {
                     
                    let res = await updateMakeupConfig(this.form)
                    if (res.code == 0) {

                        this.openAi(this.form)
                    }

                } else {
                    console.log('提交失败');
                    return false;
                }
            });
        },
        async openAi(body) {
            let that = this
            const { prompt_test, temperature_test, max_tokens_test, top_p_test, frequency_penalty_test, presence_penalty_test, model_test, imageUrl } = body
            fetch("https://api.openai.com/v1/chat/completions", {
                method: "POST",
                body: JSON.stringify({
                    model: model_test,
                    messages: [
                        {
                            role: 'system',
                            content: [
                                {
                                    type: 'text',
                                    text: prompt_test
                                }
                            ]
                        },
                        {
                            role: 'user',
                            content: [
                                {
                                    type: 'image_url',
                                    image_url: {
                                        url: imageUrl
                                    }
                                }
                            ]
                        }
                    ],
                    stream: true,
                    response_format: {
                        type: 'text'
                    },
                    temperature: Number(temperature_test),
                    max_tokens: Number(max_tokens_test),
                    top_p: Number(top_p_test),
                    frequency_penalty: Number(frequency_penalty_test),
                    presence_penalty: Number(presence_penalty_test)
                }),
                headers: {
                    "Content-Type": "application/json",
                    'Authorization': `Bearer   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`
                },
            })
                .then((response) => {
                    this.bloading = false
                    this.messageRes.content = ''
                    this.dialogVisible = true
                    const reader = response.body.getReader();
                    const decoder = new TextDecoder("utf-8"); // 指定解码器为 UTF-8
                    let receivedData = ""; // 累积接收的数据块
                    function processMessages() {
                        const messages = receivedData.split("\n");
                        for (let i = 0; i < messages.length - 1; i++) {
                            const message = messages[i];
                            // 处理完整的消息
                            that.formatDataStr(message, that.handleResult);
                        }
                        // 存储剩余未处理的数据，以便下一次数据块到达时使用
                        receivedData = messages[messages.length - 1];
                    }

                    function read() {
                        return reader.read().then(({ done, value }) => {
                            if (done) {
                                // 接收完成
                                // console.log("接收完所有数据");
                                // 将助手的回复添加到对话中

                                return;
                            }

                            // 累积接收的数据块
                            receivedData += decoder.decode(value);
                             
                            // 检查是否有完整的消息
                            if (receivedData.includes("\n")) {
                                processMessages();
                            }

                            // 继续读取下一个数据块
                            return read();
                        });
                    }
                    return read();
                })
                .catch((error) => {
                    console.log(error);

                    this.bloading = false

                    this.$message.error('请刷新重试！');

                    if (error.name === "AbortError") {
                        // console.log("请求被中断");
                    } else {
                        console.error("请求出错:", error);
                    }
                });
        },
        // 接收流回复 拼接到消息
        handleResult(result) {
            this.$set(
                this.messageRes,
                'content',
                this.messageRes.content + result
            );
         
        },
        // 处理消息格式
        formatDataStr(str, callback) {
            str.split("\n").forEach((line) => {
                if (line.trim().length > 20) {
                    line.split("data:").forEach((dataSection) => {
                        if (dataSection.trim().length > 10) {
                            const dataObject = JSON.parse(dataSection.trim());
                            if (dataObject.choices[0].delta.content) {
                                callback(dataObject.choices[0].delta.content);
                            }
                        }
                    });
                }
            });
        },
        async getMore() {
             
            let { data } = await getMakeupConfig(this.queryParams);
             
            this.form = { ...data, imageOption: 'link', imageUrl: '' };
            this.elloading.close();

        },
        handleQuery() {
            this.elloading = this.$loading({
                lock: true,
                text: 'Loading',
                spinner: 'el-icon-loading',
                background: 'rgba(0, 0, 0, 0.7)'
            });
            this.queryParams.page = 1;
            this.getMore();
        },
        async affirm() {
            this.$refs["ruleForm1"].validate(async (valid) => {
                if (!valid) return;
                this.addLoading = true;
                this.form1.version = this.form1.version.trim();
                if (!this.validateVersionFormat(this.form1.version)) {
                    this.addLoading = false;
                    this.$message.error('版本号格式不正确，应为 x.y.z');
                    return;
                }
                const res = await addMakeupVersion(this.form1)
                if (res.code != 0) {
                    this.$message.error(res.msg);
                } else {
                    this.elloading = this.$loading({
                        lock: true,
                        text: 'Loading',
                        spinner: 'el-icon-loading',
                        background: 'rgba(0, 0, 0, 0.7)'
                    });
                    this.queryParams.version = this.form1.version.trim();
                    this.getversionList();
                    this.$message.success("success");

                }
                this.form1.version = ''
                this.addLoading = false;
                this.dialogVisible1 = false;
            });
        },

        handleEdit(i, row) {
            this.form = { ...row };
            this.dialogVisible = true;
        },
        handleDelete(index, row) {
            this.form = { ...row };
            this.admDialogVisible = true;
        },
        //去评论列表 1=未回复4星以下  2=未回复5星  3=已回复4星 4=已回复5星
        goCommentList(i) {
            this.$router.push({
                path: "/review/commentList",
                query: { index: i, package_name: this.form.package_name },
            });
        },
        //跳转模板类型
        toTemplateType() {
            this.$router.push({
                path: "/review/templateType",
                query: { package_name: this.form.package_name },
            });
        },
        //跳转普通回复模板
        toTemplateManage() {
            this.$router.push({
                path: "/review/templateManage",
                query: { package_name: this.form.package_name },
            });
        },
        //跳转五星回复模板
        toFiveTemplate() {
            this.$router.push({
                path: "/review/fiveTemplate",
                query: { package_name: this.form.package_name },
            });
        },
    },
};
</script>
<style lang="scss" scoped>
.boxs {
    padding: 20px;
}

.dialog-content {
    .item {
        margin-bottom: 20px;
    }

    .title {
        font-size: 16px;
        margin-bottom: 20px;
        color: #333;
    }
}

::v-deep .v-md-pre-wrapper {
    //   font-size: 20px !important;
}



::v-deep .vuepress-markdown-body pre,
.vuepress-markdown-body pre[class*="v-md-prism-"] {
    color: none !important;
    padding: 10px;
    margin: 10px;
}

::v-deep .vuepress-markdown-body div[class*="v-md-pre-wrapper-"]:before {
    position: absolute;
    top: 8px;
    right: 10px;
    z-index: 3;
}



::v-deep .vuepress-markdown-body pre[class*="v-md-prism-"] {
    //   font-size: 20px;
    padding: 20px;
}



::v-deep .vuepress-markdown-body code {
    padding: 2px 4px;
    margin: 0 2px;
    color: #fff;
    background: rgba(93, 99, 107, 0.5);
}

::v-deep .el-dialog__body {
    padding: 0;
}

::v-deep .vuepress-markdown-body:not(.custom) {

    padding: 20px;
}
</style>
